package org.springblade.modules.admin.service.impl;

import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.es.SearchParamDTO;
import org.springblade.modules.admin.entity.es.ElevatorDocument;
import org.springblade.modules.admin.mapper.es.ElevatorDocumentMapper;
import org.springblade.modules.admin.service.ElevatorService;
import org.springblade.modules.admin.service.IElevatorSearchService;
import org.springblade.modules.admin.vo.ElevatorVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class ElevatorSearchServiceImpl implements IElevatorSearchService {

	@Autowired
	private ElevatorService elevatorService;
	@Autowired
	private ElevatorDocumentMapper elevatorDocumentMapper;


	@Override
	public void init() {
		List<ElevatorDocument> elevatorData = new ArrayList<>();
		List<ElevatorVO> list = elevatorService.selectAllElevatorDetailList();
		for (ElevatorVO elevator : list) {
			ElevatorDocument document = new ElevatorDocument();
			document.setId(elevator.getId());
			document.setName(elevator.getElevatorAddress());
			document.setNamePinyin(elevator.getElevatorAddress());
			document.setAlias(elevator.getElevatorAlias());
			document.setAliasPinyin(elevator.getElevatorAlias());
			document.setBuildingId(elevator.getBuildingId());
			document.setTenantId(elevator.getTenantId());
			elevatorData.add(document);
		}
		elevatorDocumentMapper.insertBatch(elevatorData);
	}

	@Override
	public List<ElevatorDocument> listDocumentByTitle(SearchParamDTO searchParam) {
		LambdaEsQueryWrapper<ElevatorDocument> wrapper = new LambdaEsQueryWrapper<>();
		//目前采用自定义分词器的方式,先用ik分词器分词,然后是用pinyin分词器对ik分词后的结果单独进行分词,目前这种效果最佳
		if (Func.isNotBlank(searchParam.getSearchKey())) {
			Pattern p = Pattern.compile("[\\u4e00-\\u9fa5]");
			Matcher m = p.matcher(searchParam.getSearchKey());
			if (m.find()) {
				// 含有中文
				wrapper.and(t -> t.matchPhrase(ElevatorDocument::getName, searchParam.getSearchKey()).or()
					.matchPhrase(ElevatorDocument::getAlias, searchParam.getSearchKey()));
			} else {
				// 拼音
				wrapper.and(t -> t.matchPhrase(ElevatorDocument::getNamePinyin, searchParam.getSearchKey()).or()
					.matchPhrase(ElevatorDocument::getAliasPinyin, searchParam.getSearchKey()));
			}
		}

		if (Func.isNotBlank(searchParam.getTenantId())) {
			wrapper.eq(ElevatorDocument::getTenantId, searchParam.getTenantId());
		}
		if (Func.isNotBlank(searchParam.getBuildingIds())) {
			wrapper.in(ElevatorDocument::getBuildingId, Func.toStrList(",", searchParam.getBuildingIds()));
		}
		List<ElevatorDocument> elevatorDocuments = elevatorDocumentMapper.selectList(wrapper);
		if (Func.isEmpty(elevatorDocuments)) {
			return elevatorDocuments;
		}

		// 去掉未命中的别名高亮内容
		if (Func.isNotEmpty(elevatorDocuments) && Func.isNotBlank(searchParam.getSearchKey())) {
			for (ElevatorDocument elevatorDocument : elevatorDocuments) {
				String aliasHighlightContent = elevatorDocument.getAliasHighlightContent();
				if (Func.isBlank(aliasHighlightContent)) {
					continue;
				}
				List<String> aliasList = Func.toStrList(",", aliasHighlightContent).stream().filter(t -> t.contains("<em>")).collect(Collectors.toList());
				elevatorDocument.setAliasHighlightContent(aliasList.stream().collect(Collectors.joining(",")));
			}
		}

		/**
		 * 排序规则：
		 * 关键字直接匹配，优先级最高,否则，则根据命中位置越前，优先级越高。
		 */
		elevatorDocuments = elevatorDocuments.stream().sorted(Comparator.comparingInt(t -> {
			// 默认权重值
			int score = 500;
			int nameScore = t.getName().toLowerCase().indexOf(searchParam.getSearchKey());
			if (nameScore >= 0) {
				score = nameScore;
			}

			if (Func.isNotBlank(t.getAlias())) {
				int aliasScore = t.getAlias().toLowerCase().indexOf(searchParam.getSearchKey());
				if (aliasScore >= 0 && aliasScore < score) {
					score = aliasScore;
				}
			}

			if (score == 500) {
				if (Func.isNotBlank(t.getHighlightContent())) {
					int lightNameScore = t.getHighlightContent().indexOf("<em>");
					if (lightNameScore >= 0 && lightNameScore < score) {
						// 为了避免高于关键字直接匹配优先级，这里权重值+100
						score = lightNameScore + 100;
					}
				}

				if (Func.isNotBlank(t.getAliasHighlightContent())) {
					int lightAliasScore = t.getAliasHighlightContent().indexOf("<em>");
					if (lightAliasScore >= 0 && lightAliasScore < score) {
						// 为了避免高于关键字直接匹配优先级，这里权重值+100
						score = lightAliasScore + 100;
					}
				}
			}

			return score;
		})).collect(Collectors.toList());

		return elevatorDocuments;
	}
}
